import paho.mqtt.client as mqtt
import json
import logging
import redis
import threading
import time
from util import get_mac_address
from serial_connect import SerialPortMethod
from crc import crc16_modbus
from command_parse import CommandParse
from setting import *

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger(__name__)


class MQTTClient:

    def __init__(self, broker_address, broker_port, client_name):
        self.client = mqtt.Client(client_name, protocol=mqtt.MQTTv311, transport="tcp")  # 使用 MQTTv311 协议
        self.broker_address = broker_address
        self.broker_port = broker_port

        # 设置连接成功和消息接收的回调函数
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message

        self.r = redis.Redis(host='localhost', port=6379, db=0)

        # 开启上交数据线程
        self.publish_senor_info_thread = threading.Thread(target=self.publish_senor_info)

    def on_connect(self, client, userdata, flags, rc):
        print("Connected with result code " + str(rc))
        mac = get_mac_address()
        self.client.subscribe(MQTT_DATA_CENTER_TX_TOPIC)
        logger.info("订阅MQTT Topic: {}".format(MQTT_DATA_CENTER_TX_TOPIC))

    def on_message(self, client, userdata, msg):
        per_msg = json.loads(msg.payload.decode())
        logger.info("MQTT接收信息：{}  {}".format(msg.topic, per_msg))

        if per_msg.get("task_type") == "test":
            self.client.publish(MQTT_DATA_CENTER_RX_TOPIC, json.dumps({"mac": MAC}))
            logger.info("MQTT回调数据: {}".format({"mac": MAC}))

        # 处理其他任务类型的代码（省略）
        # ...

    def connect(self):
        self.client.connect(self.broker_address, self.broker_port, 60)
        self.client.loop_start()  # 使用 loop_start() 来非阻塞地处理网络循环

    def disconnect(self):
        self.client.loop_stop()
        self.client.disconnect()

    def publish_message(self, topic, message):
        self.client.publish(topic, message)

    def publish_senor_info(self):
        logger.info("开启日常数据提交线程")
        while True:
            try:
                item = self.r.blpop(STATION_DATA_STACK)  # 取出提交的数据
                command = item[1].decode()
                parse_data = CommandParse(command).parse_result
                result = {
                    "type": "senorInfo",
                    "data": {
                        "devaddr": 1,
                        "text": command,
                        "parse_data": parse_data
                    }
                }
                topic = f"iot/devices/test/baina/{MAC}/allinone/rx"
                self.client.publish(topic, json.dumps(result))
            except Exception as e:
                logger.error(f"提交传感器信息错误：{str(e)}")
                logger.error(item)
                time.sleep(5)
            else:
                logger.info("topic:{}：提交数据：{}".format(topic, result))


def run_mqtt_client():
    mqtt_client = MQTTClient(broker_address="47.110.239.14", broker_port=1883,
                             client_name="cabinet-{}".format(get_mac_address()))
    mqtt_client.publish_senor_info_thread.start()
    mqtt_client.connect()


if __name__ == "__main__":
    run_mqtt_client()